package pl.edu.agh.mguesser.ui.main;

import com.google.common.io.Resources;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.EnumSet;
import java.util.List;
import java.util.Set;
import javax.annotation.PostConstruct;
import javax.imageio.ImageIO;
import javax.swing.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Controller;
import pl.edu.agh.mguesser.exception.MusicGuesserRuntimeException;
import pl.edu.agh.mguesser.game.*;
import pl.edu.agh.mguesser.game.listener.StartGameMediator;
import pl.edu.agh.mguesser.ui.SizeConstants;
import pl.edu.agh.mguesser.ui.Window;
import pl.edu.agh.mguesser.ui.game.GameInProgress;
import pl.edu.agh.mguesser.ui.swing.ImagePanel;
import pl.edu.agh.mguesser.user.User;

/**
 * @author keiran
 */
@Controller
public class NewGame extends JPanel {
    
    @Autowired
    private ApplicationContext context;
    
    @Autowired
    private StartGameMediator startGameMediator;
    
    @Autowired
    private Window window;
    @Autowired
    private GameInProgress gameInProgress;
    @Autowired
    private MainMenu mainMenu;
    
    private JList<String> usersList;
    private JSpinner roundsSpinner;
    private JCheckBox randomizePlaylistCheckbox;
    private JCheckBox randomizeSongPositionCheckbox;
    private JComboBox<GameMode> gameModeCombo;
    
    private JTextField playlistTextField;
    private JButton playlistBtn;
    private JFileChooser playlistChooser;
    
    private JButton goBtn;
    private JButton backBtn;
    
    @PostConstruct
    public void postConstruct() {
        setLayout(new BorderLayout());
        
        addTopBar();
        addMiddlePanel();
        addBottomButtons();
        
        bindPlaylist();
        bindBottomButtons();
    }

    private void addTopBar() {
        try {
            BufferedImage image = ImageIO.read(Resources.getResource("img/top_bar.jpg"));
            
            JPanel panel = new ImagePanel(image);
            Dimension size
                    = new Dimension(SizeConstants.WINDOW_WIDTH, SizeConstants.TOP_BAR_HEIGHT);
            panel.setPreferredSize(size);
            add(panel, BorderLayout.NORTH);
            
        } catch(IOException ex) {
            throw new MusicGuesserRuntimeException(ex);
            
        }
    }

    private void addMiddlePanel() {
        JPanel center = new JPanel(new GridLayout(3, 2));
        
        DefaultListModel usersListModel = new DefaultListModel();
        usersListModel.addElement("KEIRAN");
        usersListModel.addElement("BLACHA");
        usersList = new JList(usersListModel);
        
        SpinnerNumberModel roundsSpinnerModel = new SpinnerNumberModel(5, 5, 100, 5);
        roundsSpinner = new JSpinner(roundsSpinnerModel);
        
        randomizePlaylistCheckbox = new JCheckBox("randomize playlist");
        randomizePlaylistCheckbox.setSelected(true);
        
        randomizeSongPositionCheckbox = new JCheckBox("randomize song position");
        randomizeSongPositionCheckbox.setSelected(true);
        
        DefaultComboBoxModel<GameMode> gameModeComboModel = new DefaultComboBoxModel<>();
        gameModeComboModel.addElement(GameMode.ONE_BY_ONE);
        gameModeCombo = new JComboBox(gameModeComboModel);
        
        JPanel playlistPanel = new JPanel(new FlowLayout());
        playlistTextField = new JTextField(20);
        playlistTextField.setEnabled(false);
        playlistTextField.setText("/home/keiran/Pulpit/all.m3u");
        playlistBtn = new JButton("Open");
        playlistChooser = new JFileChooser();
        playlistPanel.add(playlistTextField);
        playlistPanel.add(playlistBtn);
        
        center.add(usersList);
        center.add(roundsSpinner);
        center.add(randomizePlaylistCheckbox);
        center.add(randomizeSongPositionCheckbox);
        center.add(gameModeCombo);
        center.add(playlistPanel);
        
        add(center, BorderLayout.CENTER);
    }

    private void addBottomButtons() {
        JPanel buttonsPanel = new JPanel(new FlowLayout(FlowLayout.CENTER));
        
        goBtn = new JButton("Go!");
        buttonsPanel.add(goBtn);
        
        backBtn = new JButton("To Main Menu");
        buttonsPanel.add(backBtn);
        
        add(buttonsPanel, BorderLayout.SOUTH);
    }
    
    private void bindPlaylist() {
        playlistBtn.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent event) {
                int returnVal = playlistChooser.showOpenDialog(window);

                if (returnVal == JFileChooser.APPROVE_OPTION) {
                    File file = playlistChooser.getSelectedFile();
                    playlistTextField.setText(file.getAbsolutePath());
                }
            }
        });
    }
    
    private void bindBottomButtons() {
        goBtn.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent event) {
                try {
                    GameSettingsBuilder builder = new GameSettingsBuilder();
                    
                    Set<Options> options = EnumSet.noneOf(Options.class);
                    if(randomizePlaylistCheckbox.isSelected()) {
                        options.add(Options.RANDOMIZE_PLAYLIST);
                    }
                    if(randomizeSongPositionCheckbox.isSelected()) {
                        options.add(Options.RANDOMIZE_SONG_POSITION);
                    }
                    builder.setOptions(options);
                    
                    List<User> users = new ArrayList<>();
                    for(String userName : usersList.getSelectedValuesList()) {
                        users.add(new User(userName));
                    }
                    builder.setUsers(users);
                    
                    builder.setRounds((int) roundsSpinner.getValue());
                    
                    builder.setPlaylist(Paths.get(playlistTextField.getText()));
                    
                    GameSettings settings = builder.build();
                    
                    GameMode selectedGameMode = (GameMode) gameModeCombo.getSelectedItem();
                    GameFlow gameFlow = (GameFlow) context.getBean(selectedGameMode.getImplementationType());
                    
                    gameFlow.setGameSettings(settings);
                    startGameMediator.injectListeners(gameFlow);
                    
                    gameFlow.gameStarting();
                    
                    gameInProgress.setGameFlow(gameFlow);
                    window.changePanel(gameInProgress);
                    
                } catch(GameSettingsBuilderException ex) {
                    throw new MusicGuesserRuntimeException(ex);
                    
                }
            }
        });
        
        backBtn.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent event) {
                window.changePanel(mainMenu);
            }
        });
    }
    
}
